﻿(function() {

    function $logf(func)
    {
        return function ()
        {
            console.group(this.id, this.name, func);
            func.apply(this, arguments);
            $loge();
        };
    }
    function $logfc(func)
    {
        return function ()
        {
            console.groupCollapsed(this.id, this.name, func);
            $trace();
            func.apply(this, arguments);
            $loge();
        };
    }
    
    function $_logf(func){return func;}
    function $_logfc(func) { return func; }


    Ext.define('Ext.uis.TermNode', {
        statics: {
            objects: { },
            get: function(id) {
                var node = Ext.uis.TermNode.objects[id];
                if (!node)
                    throw new Error('[Ext.uis.TermNode.get] Can\'t find TermNode by id = \'' + id + '\'.');
                return node;
            }
        },

        //mixins: {
        //    observable: 'Ext.util.Observable'
        //},

        items: [],

        constructor: function(cfg) {
            if (!cfg || !cfg.id)
                throw new Error('[Ext.uis.TermNode] Can\'t create without config.id.');

            var me = Ext.apply(this, cfg);

            //me.mixins.observable.constructor.call(me, cfg);
            //me.addEvents('fieldChanged');

            Ext.uis.TermNode.objects[me.id] = me;
            if (me.items) {
                for (var i = 0, item; item = me.items[i++];) {
                    item.parent = me;
                }
            }
        },

        destroy: function() {
            if (this.controlListeners) {
                this.control.un(this.controlListeners);
            }
            if (this.storeListeners) {
                this.store.un(this.storeListeners);
            }
        },


        getStore: $_logfc(function TermNode_getStore() {
            var me = this;
            if (me.store === null) return null;

            if (me.store) {
                if (Ext.isString(me.store))
                    me.store = Ext.StoreManager.get(me.store);
                return me.store;
            }

            var p = me, parents = [];
            while (p != null && !p.store) {
                parents.push(p);
                p = p.parent;
            }

            if (p == null)
                return null;
            var store = p.store;
            if (Ext.isString(store))
                p.store = store = Ext.StoreManager.get(store);
            for (var i = 0, pp; pp = parents[i++];) {
                pp.store = store;
            }
            return store;
        }),

        applyToField: $_logfc(function TermNode_applyToField(control) {
            var me = this;
            me.store = this.getStore();
            if (me.store) {
                me.storeListeners = {
                    activate: me.onFieldActivate,
                    update: me.onFieldUpdate,
                    scope: me
                };
                //$log('initStore. Set events');
                me.store.on(me.storeListeners);
            }

            me.control = control;
            me.controlListeners = { change: me.onFieldChange, scope: me };
            control.on(me.controlListeners);
            me.setControlEnabled = function(enabled) { control.setDisabled(!enabled); };
        }),

        onFieldActivate: $logf(function TermNode_onFieldActivate() {
            if (this.nowActivateModel) return;
            this.nowActivateModel = true;
            try {
                this.setValue(this.store.geta(this.name));
            } finally {
                this.nowActivateModel = false;
            }
        }),

        onFieldUpdate: $logf(function TermNode_onFieldUpdate(store, record, operation, modifiedFieldNames) {
            var me = this;
            if (operation == Ext.data.Model.EDIT && modifiedFieldNames.indexOf(me.name) < 0) return;
            if (me.nowUpdateModel) return;

            me.nowUpdateModel = true;
            try {
                if (!me.nowFieldChange) {
                    $log('control.setValue');
                    me.setValue(store.geta(me.name));
                }
            } finally {
                me.nowUpdateModel = false;
            }
        }),

        onFieldChange: $logf(function TermNode_onFieldChange(sender, value) {
            if (!this.store || this.nowActivateModel || this.nowFieldChange || this.nowUpdateModel) return;

            this.nowFieldChange = true;
            try {
                this.store.seta(this.name, value);
            } finally {
                this.nowFieldChange = false;
            }
        }),

        getValue: $logf(function TermNode_getValue() {
            return (
                this.control && this.control.getValue ? this.control.getValue() :
                    this.getStore.geta(this.name)
            );
        }),
        setValue: $logf(function TermNode_setValue(value) {
            var me = this;
            if (me.control && me.control.setValue) {
                me.control.setValue(value);
            } else {
                me.store.seta(me.name, value);
            }
        }),


        enabled: true,
        setEnabled: $logf(function TermNode_setEnabled(value) {
            if (this.enabled !== value) {
                this.enabled = value;
                if (this.setControlEnabled)
                    this.setControlEnabled(value);
            }
        }),

        __xxx: null
    });
})();

Ext.uisGet = Ext.uis.TermNode.get;